package kr.co.sdsway2.service;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.annotation.Resource;

import kr.co.sdsway2.common.AbstractService;
import kr.co.sdsway2.vo.AvatarVO;

import org.springframework.stereotype.Service;

@Service
public class AvatarService extends AbstractService {

	/* 좌표 범위 */
	private int minPosX = 0;
	private int minPosY = 100;
	private int maxPosX = 974;
	private int maxPosY = 718;

	@Resource(name="avatarVOList")
	private List<AvatarVO> avatarVOList;

	/** 좌표 범위 설정 서비스 */
	public void setPosition(int minX, int minY, int maxX, int maxY) {
		minPosX = minX;
		minPosY = minY;
		maxPosX = maxX;
		maxPosY = maxY;
	}

	/** 아바타 삽입 서비스 */
	public void insertAvatar(String avatarId,String avatarType) {
		int defaultPosX = 100;
		int defaultPosY = 100;
		
		AvatarVO vo = new AvatarVO();
		vo.setAvatarId(avatarId);
		vo.setAvatarType(avatarType);
		vo.setPosX(defaultPosX);
		vo.setPosY(defaultPosY);
		vo.setAvatarScore(0);

		avatarVOList.add(vo);
	}

	/** 아바타 삭제(아바타ID) 서비스 */
	public void remove(String avatarId) {
		int idx = getIndex(avatarId);
		if( idx != -1 ) this.avatarVOList.remove(idx);
	}

	/** 아바타 삭제(아바타 index) 서비스 */
	public void remove(int idx){
		this.avatarVOList.remove(idx);
	}

	/** 아바타 목록 조회 서비스 */
	public List<AvatarVO> getList(){
		return this.avatarVOList;
	}

	/** 아바타 조회 서비스 */
	public AvatarVO getAvatar(String avatarId) {
		int i = getIndex(avatarId);
		if(i>=0){
			return avatarVOList.get(i);
		}
		return null;
	}

	/** 아바타 수정(이동) 서비스 */
	public void move(String avatarId,int xDist,int yDist,String avatarType){
		AvatarVO vo = null;
		int i = getIndex(avatarId);
		int x, y;
		if(i>=0){
			vo = avatarVOList.get(i);
			vo.setAvatarType(avatarType);
			x = vo.getPosX() + xDist;
			y = vo.getPosY() + yDist;
			if( x < minPosX ) x = minPosX;
			else if( x > maxPosX ) x = maxPosX;
			if( y < minPosY ) y = minPosY;
			else if( y > maxPosY ) y = maxPosY;
			vo.setPosX(x);
			vo.setPosY(y);
		}
	}

	/** 아바타ID를 통해 index 획득 */
	private int getIndex(String avatarId){
		int idx = -1;
		int size = avatarVOList.size();
		AvatarVO vo;
		for(int i=0;i<size;i++){
			vo = avatarVOList.get(i);
			if(vo!=null && vo.getAvatarId()!=null){
				if(vo.getAvatarId().equals(avatarId))
					idx = i;
			}
		}
		return idx;
	}

	public void sortAvatarVOList() {
		new MergeSort().sort(avatarVOList);
	}

	/** 복사 */
	private void copy(AvatarVO aVO, AvatarVO bVO) {
		bVO.setAvatarId(aVO.getAvatarId());
		bVO.setAvatarScore(aVO.getAvatarScore());
		bVO.setAvatarType(aVO.getAvatarType());
		bVO.setMessage(aVO.getMessage());
		bVO.setPosX(aVO.getPosX());
		bVO.setPosY(aVO.getPosY());
	}

	/** 병합정렬 */
	public class MergeSort {
		private CopyOnWriteArrayList<AvatarVO> targetList;
		private CopyOnWriteArrayList<AvatarVO> helperList;
		private int targetSize;

		public void sort(List<AvatarVO> avatarVOList) {
			targetList = (CopyOnWriteArrayList<AvatarVO>)avatarVOList;
			targetSize = targetList.size();
			helperList = new CopyOnWriteArrayList<AvatarVO>();
			for(int i=0; i<targetSize; i++) helperList.add(new AvatarVO());
			mergeSort(0, targetSize-1);
		}

		private void mergeSort(int low, int high) {
			if( low < high ) {
				int middle = low + (high-low)/2;
				mergeSort(low, middle);
				mergeSort(middle+1, high);
				merge(low, middle, high);
			}
		}

		private void merge(int low, int middle, int high) {
			for(int i=low; i<=high; i++) copy(targetList.get(i), helperList.get(i));
			
			int i = low;
			int j = middle + 1;
			int k = low;
			while( i<=middle && j<=high ) {
				if( helperList.get(i).getAvatarScore() >= helperList.get(j).getAvatarScore() ) {
					copy(helperList.get(i), targetList.get(k));
					i++;
				}
				else {
					copy(helperList.get(j), targetList.get(k));
					j++;
				}
				k++;
			}
			while( i <= middle ) {
				copy(helperList.get(i), targetList.get(k));
				k++;
				i++;
			}
		}
	}

}
